#ifndef __DBMANAGER_H__
#define __DBMANAGER_H__

#define DBAPP DBManager::getInstance()

#include <iostream>
#include <mutex>
#include <mysql.h>

class DBManager
{
public:
    static DBManager* getInstance();
    void init();

    ~DBManager();

    /**
     * 1. 实现注册、登录功能
     *  1. 查询用户
     *  2. 插入用户数据
    */
   bool isUserExist(const std::string &user);
   bool registerUser(const std::string &user, 
                     const std::string &passwd, 
                     const std::string &phone, 
                     const std::string &email, 
                     const std::string &data);
    /**
     * 功能：检查密码
     * 参数：user: 用户名, password: 待检查的密码
     * 返回值: 用户 ID
    */
    int checkUserPassword(const std::string &user, const std::string &password);

    /**
     * 检查表是否存在
     * 参数：user: 用户名
     * 返回值：true：存在，false：不存在
     */
    bool isTableExist(const std::string &table_name);
    /**
     * 检查用户数据表是否存在
     * 用户数据表名称：用户名_年份
     * 参数：user: 用户名
     * 返回值：true：存在，false：不存在
     */
    bool isDataTableExist(const std::string &user);

    /**
     * 创建用户数据表
     * 用户数据表名称：用户名_年份
     * 参数：user: 用户名
     * 返回值：true：成功，false：失败
     */
    bool createDataTable(const std::string &user);
    
    /**
     * 创建分类大类数据表
     * 返回值：true：成功，false：失败
     */
    bool createMainTypeTable();
    
    /**
     * 插入一条分类大类数据
     * 参数：
     * user_id: 关联用户 ID
     * income: 是否为收入类型，true：收入类型，false：支出类型
     * 大类名称（type）
     * 返回值：true：成功，false：失败
     */
    bool addMainType(int user_id, bool income, const std::string &type);

    /**
     * 创建分类小类数据表
     * 返回值：true：成功，false：失败
     */
    bool createSubTypeTable();
private:
    static DBManager* self;
    static std::mutex self_mutex;

    MYSQL *sql_conn;

private:
    DBManager(/* args */);

    std::string getCurrentYear();
    /**
     * 初始化收入分类数据
     */
    bool initIncomeType();
    /**
     * 初始化支出大类数据
     */
    bool initOutcomeMainType();
    /**
     * 初始化支出小类数据
     */
    bool initOutcomeSubType();

    /**
     * 查看主类是否存在
     * 返回值：用户 ID；-1：主类不存在，
     */
    int isMainTypeExist(int user_id, bool income, const std::string &type);
};


#endif //__DBMANAGER_H__